/**
 * This class draws scatter plot for the given input attributes and preprocessed file
 */
package org.wmine.visualization;

import java.awt.Color;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JOptionPane;
import javax.xml.parsers.ParserConfigurationException;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.wmine.core.ProjectManager;
import org.wmine.data.Attribute;
import org.wmine.data.DataSet;
import org.wmine.data.InvalidCursorPositionException;
import org.wmine.data.TableResultSet;
import org.wmine.data.XMLDataReader;
import org.xml.sax.SAXException;

/**
 * @author Rajeev Kumar Thakur
 *
 */
public class DrawScatterPlot implements IDrawMiningAlgorithmOutput{

	private String inputFileName, attributeX , attributeY;
	ArrayList<Double> dataX, dataY;
	DataSet dataSet;
	public DrawScatterPlot(String sctrInputFileName, String sctrAttrib1, String sctrAttrib2) {
		// TODO Auto-generated constructor stub
		inputFileName = new String();
		attributeX = new String();
		attributeY = new String();
		dataX = new ArrayList<Double>();
		dataY = new ArrayList<Double>();
		inputFileName = sctrInputFileName;
		attributeX = sctrAttrib1;
		attributeY = sctrAttrib2;
		 dataSet = new DataSet();
		try {
			dataSet.setDataReader(new XMLDataReader(new StringBufferInputStream(ProjectManager.getUniqueInstance().readFile(inputFileName))));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	
	}

	public SetChartPanel drawGraph() throws ParserConfigurationException, SAXException, IOException {
		// TODO Auto-generated method stub
		JFreeChart chart;
		SetChartPanel setChart;
		TableResultSet resultSet = dataSet.getTableResultSet();
		resultSet.reset();
		if(checkAttributType())	{		
		while (resultSet.hasNext()) {
			try {
				dataX.add(Double.parseDouble(resultSet.getString(attributeX)));
				dataY.add(Double.parseDouble(resultSet.getString(attributeY)));
			} catch (NumberFormatException e) {
				// TODO Auto-generated catch block
				
				e.printStackTrace();
			} catch (InvalidCursorPositionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			}
		chart = setupChartProperties();
		setChart = new SetChartPanel(chart);
		}
		else {
			JOptionPane.showMessageDialog(null, "Select the Numerical data for both the Axis");
			setChart = null;
		}
		
		
		return setChart;
	}
	private boolean checkAttributType() {
		// TODO Auto-generated method stub
		boolean flag = true; 
		Iterator <Attribute> iterAttrib;
		iterAttrib = dataSet.getAttributeIterator();
		while (iterAttrib.hasNext()) {
			Attribute element = (Attribute) iterAttrib.next();
			String name = element.getAttributeName();
			String type = element.getAttributeType();
			if(name.equals(attributeX)){
				if (type.equals("String")) {
					flag = false;
					break;
				}					
			}
			if(name.equals(attributeY)){
				if (type.equals("String")) {
					//JOptionPane.showMessageDialog(null, "Select the Numerical data as attribute");
					flag = false;
					break;
				}					
			}
		
		}
		return flag;
	}

	protected JFreeChart setupChartProperties() {
		JFreeChart chart;
		XYSeries chartSeries1 = new XYSeries("Scatter Plot");
	
		 
		
		//Add your values here
		for(int i = 0; i<dataX.size(); i++) {
			chartSeries1.add(dataX.get(i), dataY.get(i));
		}
		
		
		XYSeriesCollection seriesCollection = new XYSeriesCollection();
		
		seriesCollection.addSeries(chartSeries1);
		XYDataset dataset = seriesCollection;
		chart = ChartFactory.createXYLineChart(
				"Scatter Plot Between Two Attributes",      // chart title
				 attributeX,                      // x axis label
				 attributeY,                      // y axis label
				dataset,                  // data
				PlotOrientation.VERTICAL,
				true,                     // include legend
				true,                     // tooltips
				false                     // urls
		);

		// NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
		chart.setBackgroundPaint(Color.white);

//		final StandardLegend legend = (StandardLegend) chart.getLegend();
		//      legend.setDisplaySeriesShapes(true);

		// get a reference to the plot for further customisation...
		final XYPlot plot = chart.getXYPlot();
		plot.setBackgroundPaint(Color.white);
		//    
		plot.setDomainGridlinePaint(Color.lightGray);
		plot.setRangeGridlinePaint(Color.lightGray);

 		final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
		renderer.setSeriesLinesVisible(0, false);
		renderer.setSeriesShapesVisible(1, false);
		plot.setRenderer(renderer);
 
		// change the auto tick unit selection to integer units only...
		final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
		rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
		return chart;
	} 	
}
